﻿using Peak.Can.Basic;
using Peak.Can.Uds;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Channels;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WindowsFormsApp1;

namespace 项目模板2.Communication
{
    using TPCANHandle = System.UInt16;
    

    public enum DeviceProtocol
    {
        DEVICE_MODE_NONE = -1,
        DEVICE_MODE_BASIC ,
        DEVICE_MODE_UDS_DTC,
        DEVICE_MODE_UDS_BOOT,
        DEVICE_MODE_CCP,
    }

    public class DeviceM
    {
        #region 通信参数
        public TPCANBaudrate Baud { get; set; }

        public TPCANHandle UsbChl { get; set; }

        public bool getMessages = false;

        public Form1 form1 { get; set; }

        #endregion


        #region 连接、断开事件
        public delegate void DeviceConnectDelegate();
        public delegate void RecvDelegate(TPCANMsg CANMsg);

        public event DeviceConnectDelegate ConnectEvent;
        public event DeviceConnectDelegate DisonnectEvent;
        public event RecvDelegate RecvEvent;
        #endregion
        public DeviceProtocol Protocol { get; set; }

        public bool ConnetcState { get; set; }
        public bool InitState { get; set; }
        Thread ReceiveThread;

       public TPUDSNetAddrInfo N_AI;//UDS初始化参数

       public TPCANStatus Status { get; set; }//通信状态


        public bool InitDevice(TPCANBaudrate baud,TPCANHandle ch, DeviceProtocol prot,out string errStr) 
        {
            errStr = "";
            Baud = baud;
            UsbChl = ch;
            Protocol = prot;
            if (Protocol == DeviceProtocol.DEVICE_MODE_BASIC)
            {
                TPCANStatus ret = TPCANStatus.PCAN_ERROR_OK;
                ret = PCANBasic.Initialize(UsbChl, Baud);
                
                if (ret != TPCANStatus.PCAN_ERROR_OK)
                {
                    InitState = false;
                    errStr = ret.ToString();
                }
                else
                {
                    InitState = true;
                }
            }
            if ((Protocol == DeviceProtocol.DEVICE_MODE_UDS_BOOT)||(Protocol == DeviceProtocol.DEVICE_MODE_UDS_DTC))
            {
                TPUDSStatus ret = TPUDSStatus.PUDS_ERROR_OK;
                UDSApi.Initialize(UsbChl, (TPUDSBaudrate)Baud, 0, 0, 0);
                if (ret != TPUDSStatus.PUDS_ERROR_OK)
                {
                    InitState = false;
                    errStr = ret.ToString();
                }
                else
                {
                    InitState = true;
                }
            }
            return InitState;
        }

        public void Open() 
        {
            if (!InitState)
                return;
            if (Protocol == DeviceProtocol.DEVICE_MODE_BASIC)
            {
                ReceiveThread = new Thread(new ThreadStart(ReceiveFrameThread));
                ReceiveThread.Start();
            }
            ConnectEvent?.Invoke();
            ConnetcState = true;
        }

        private void ReceiveFrameThread()
        {
            while (true)
            {
                TPCANStatus ret = PCANBasic.Read(UsbChl, out TPCANMsg CANMsg, out TPCANTimestamp CANTimeStamp);

                if (ret == TPCANStatus.PCAN_ERROR_OK) //已接收到数据
                {
                    getMessages = true;
                    RecvEvent?.Invoke(CANMsg);
                    
                }
                Thread.Sleep(1);
            }
        }

        public void Close() 
        {
            if (Protocol == DeviceProtocol.DEVICE_MODE_BASIC)
            {
                ReceiveThread.Abort();
                DisonnectEvent?.Invoke();
                PCANBasic.Uninitialize(UsbChl);
                ConnetcState = false;
                InitState = false;
            }
            else if (Protocol == DeviceProtocol.DEVICE_MODE_UDS_BOOT)
            {
                UDSApi.Uninitialize(UsbChl);
                ConnetcState = false;
                InitState = false;
            }
            else if (Protocol == DeviceProtocol.DEVICE_MODE_UDS_DTC)
            {
                UDSApi.Uninitialize(UsbChl);
                ConnetcState = false;
                InitState = false;
            }
        }

        public TPCANStatus Write(byte[] frame, byte len, uint Id)
        {
            TPCANStatus ret = TPCANStatus.PCAN_ERROR_OK;
            if (!ConnetcState) 
                return TPCANStatus.PCAN_ERROR_BUSOFF;
            if (Protocol == DeviceProtocol.DEVICE_MODE_BASIC)
            {
                TPCANMsg txBuf = new TPCANMsg();
                txBuf.LEN = len;
                txBuf.ID = Id;
                txBuf.DATA = frame;
                if (Id > 0x7ff)
                {
                    txBuf.MSGTYPE = TPCANMessageType.PCAN_MESSAGE_EXTENDED;
                }
                else
                {
                    txBuf.MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD;
                }
                ret = PCANBasic.Write(UsbChl, ref txBuf);
            }
            return ret;
        }

        public TPCANStatus GetStatus()
        {
            Status = PCANBasic.GetStatus(UsbChl);
            return Status;
        }

        public void Reset()
        {
            PCANBasic.Reset(UsbChl);
            PCANBasic.Uninitialize(UsbChl);
            Thread.Sleep(1000);
        }
    }
}
